#include "mainscence.h"
#include "ui_mainscence.h"
#include"config.h"
#include<QIcon>
#include"map.h"
#include<QPainter>
#include<QMouseEvent>
#include<ctime>
#include<QSound>
#include<qmath.h>
#include<QMessageBox>
/**************///实现平滑移动所需的头文件
#include<QWidget>
#include<QKeyEvent>
#include<QtCore/QPointF>
#include<qmath.h>
/**************/
#include <QCoreApplication>


Mainscence::Mainscence(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Mainscence)
{

    ui->setupUi(this);//顺序怎么办？

    initScene();//调用初始化场景函数
    //启动游戏，调用启动游戏函数
    //playGame();
}

Mainscence::~Mainscence()
{
    delete ui;
}

/*****************************************************/
void Mainscence::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
        {
            case Qt::Key_W:
                m_upKeyPressed = true;
                gameLoop();
                break;
            case Qt::Key_S:
                m_downKeyPressed = true;
                gameLoop();
                break;
            case Qt::Key_A:
                m_leftKeyPressed = true;
                gameLoop();
                break;
            case Qt::Key_D:
                m_rightKeyPressed = true;
                gameLoop();
                break;
            //case Qt::Key_Space:
           //    m_shootKeyPressed = true;
            //    m_hero.shoot();
             if(m_stopKeyPressed==false)
             {
                case Qt::Key_P:
                     m_Timer.stop();
                     m_stopKeyPressed = true;
                     break;
             }
             if(m_stopKeyPressed==true)
             {
                 case Qt::Key_Space:
                     m_Timer.start();
                     m_stopKeyPressed=false;
                     break;
             }

            default:
                break;
        }
}

void Mainscence::keyReleaseEvent(QKeyEvent *event)
{
    switch (event->key())
       {
           case Qt::Key_W:
               m_upKeyPressed = false;
               //gameLoop();
               break;
           case Qt::Key_S:
               m_downKeyPressed = false;
               //gameLoop();
               break;
           case Qt::Key_A:
               m_leftKeyPressed = false;
               //gameLoop();
               break;
           case Qt::Key_D:
               m_rightKeyPressed = false;
           case Qt::Key_Space:
              m_stopKeyPressed = false;
             //  gameLoop();
               break;

           default:
               break;
       }
}

void Mainscence::gameLoop()//实现八个方向移动 m_upKeyPressed
{
        const qreal acceleration = 5;
        const qreal maxSpeed = 50;


        if (m_upKeyPressed)
            dy -= acceleration;
        if (m_downKeyPressed)
            dy += acceleration;
        if (m_leftKeyPressed)
            dx -= acceleration;
        if (m_rightKeyPressed)
            dx += acceleration;
        if(m_upKeyPressed&&m_leftKeyPressed)
        {
            dy -= acceleration;
            dx -= acceleration;
        }
        if(m_upKeyPressed&&m_rightKeyPressed)
        {
            dy -= acceleration;
            dx += acceleration;
        }
        if(m_downKeyPressed&&m_leftKeyPressed)
        {
            dy += acceleration;
            dx -= acceleration;
        }
        if(m_downKeyPressed&&m_rightKeyPressed)
        {
            dy += acceleration;
            dx += acceleration;
        }

        // 限制最大速度
        qreal length = sqrt(dx * dx + dy * dy);
        if (length > maxSpeed)
        {
            dx = dx * maxSpeed / length;
            dy = dy * maxSpeed / length;
        }

        // 更新目标位置
        m_targetPosition.setX(m_hero.m_X + dx);
        m_targetPosition.setY(m_hero.m_Y + dy);

           //平滑的移动到目标位置
           qreal smoothingFactor = 0.2;
           qreal newX = m_hero.m_X + smoothingFactor * (m_targetPosition.x() - m_hero.m_X);
           qreal newY = m_hero.m_Y + smoothingFactor * (m_targetPosition.y() - m_hero.m_Y);

           //边界检测
           if(newX<=0)
           {
               newX=0;
           }
           if(newX>=GAME_WIDTH-m_hero.m_Rect.width())
           {
               newX=GAME_WIDTH-m_hero.m_Rect.width();
           }
           if(newY<=0)
           {
               newY = 0;
           }
           if(newY >= GAME_HEIGHT - m_hero.m_Rect.height())
           {
               newY=GAME_HEIGHT - m_hero.m_Rect.height();
           }

           m_hero.setPosition(newX,newY);

}

/*****************************************************/
void Mainscence::playGame()
{
    //启动背景音乐（有先后顺序）
    QSound::play(SOUND_BACKGROUND);//需要QSound头文件

    //启动定时器
    m_Timer.start();


    //监听定时器发送的信号(槽)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!槽和信号，可以实现更新的东西
    connect(&m_Timer , &QTimer::timeout,[=](){


        gameLoop();
        //敌机出场
        enemyToScene();
        //更新游戏中元素的坐标
        updatePosition();
        //绘制到主屏幕中
        update();//系统自带主函数（重新绘制游戏窗口中所有信息）
        collisionDetection();
    });

}


void Mainscence::updatePosition()//让画面动起来的东西
{
    //更新地图坐标
    m_map.mapPosition();

    //发射子弹
    m_hero.shoot();

    //计算所有非空闲子弹的当前坐标（让子弹飞起来）
    for(int i=0;i<BULLET_NUM;i++)
    {
        //如果非空闲，需要更新这个子弹的坐标
        if(m_hero.m_bullets[i].m_Free==false)
        {
            m_hero.m_bullets[i].updatePosition();//此处仅更新了坐标，没有绘制
        }
    }

    //敌机出场
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free == false)//空闲敌机出场
        {
            m_enemys[i].updatePosition();
        }
    }

    //敌机发射子弹
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free == false)
        {
            m_enemys[i].shoot();
        }
    }

    for(int j=0;j<ENEMY_NUM;j++)
    {
        for(int i=0;i<BULLET_NUM;i++)
        {
            //如果非空闲，需要更新这个子弹的坐标
            if(m_enemys[j].e_bullets[i].m_Free==false)
            {
                m_enemys[j].e_bullets[i].e_updatePosition();//此处仅更新了坐标，没有绘制
            }
        }
    }

    //计算爆炸播放图片
    for(int i=0;i<BOMB_NUM;i++)
    {
        if(m_bombs[i].m_Free==false)
        {
            m_bombs[i].updateInfo();//没太看明白？？？？？？？？？？？？//还需要绘制//图片下标会在此时更新
        }
    }
}

void Mainscence::paintEvent(QPaintEvent *)
{
    QPainter painter(this);//要在当前屏幕（this）中画画
    //绘制地图
    painter.drawPixmap(0,m_map.m_map1_posY,m_map.m_map1);//初始坐标为0，末坐标随map1变动
    painter.drawPixmap(0,m_map.m_map2_posY,m_map.m_map2);

    //绘制player
    painter.drawPixmap(m_hero.m_Rect , m_hero.m_Plane);


    //绘制子弹
   for(int i=0;i<BULLET_NUM;i++)
   {
       //如果非空闲，绘制
       if(m_hero.m_bullets[i].m_Free==false)
      painter.drawPixmap(m_hero.m_bullets[i].m_X,m_hero.m_bullets[i].m_Y,m_hero.m_bullets[i].m_Bullet);
   }

   //绘制敌机
   for(int i=0;i<ENEMY_NUM;i++)
   {
       if(m_enemys[i].m_Free == false)
       {
           painter.drawPixmap(m_enemys[i].m_X , m_enemys[i].m_Y , m_enemys[i].m_enemy);
       }
   }
   \
   //绘制敌机子弹
   for (int i=0;i<ENEMY_NUM;i++)
   {
       for(int j=0;j<BULLET_NUM;j++)
       {
           if(m_enemys[i].e_bullets[j].m_Free==false)
           {
               painter.drawPixmap(m_enemys[i].e_bullets[j].m_X , m_enemys[i].e_bullets[j].m_Y , m_enemys[i].e_bullets[j].e_Bullet);
           }
       }

   }


   //绘制爆炸
   for(int i=0;i<BOMB_NUM;i++)
   {
       if(m_bombs[i].m_Free==false)
       {
           painter.drawPixmap(m_bombs[i].m_X,m_bombs[i].m_Y,m_bombs[i].m_pixArr[m_bombs[i].m_index]);//实现绘制轮番播放的贴图
       }
   }
}

void Mainscence::mouseMoveEvent(QMouseEvent * event)//需有<QMouseEvent>头文件
{
    //记录鼠标点击的位置
    int x = event->x() - m_hero.m_Rect.width()*0.5;
    int y = event->y() - m_hero.m_Rect.height()*0.5;

    //边界检测
    if(x<=0)
    {
        x=0;
    }
    if(x>=GAME_WIDTH-m_hero.m_Rect.width())
    {
        x=GAME_WIDTH-m_hero.m_Rect.width();
    }
    if(y<=0)
    {
        y = 0;
    }
    if(y >= GAME_HEIGHT - m_hero.m_Rect.height())
    {
        y=GAME_HEIGHT - m_hero.m_Rect.height();
    }

    m_hero.setPosition(x,y);//用于将飞机移到相应位置
}

void Mainscence::enemyToScene()
{
    m_recorder++;
    //未到出场时间，直接return
    if(m_recorder < ENEMY_INTERNAL)
    {
        return;
    }

    m_recorder = 0;
    for(int i=0;i<ENEMY_NUM;i++)
    {
        //如果是空闲敌机，出场
        if(m_enemys[i].m_Free)
        {
            m_enemys[i].m_Free = false;

            //出现点坐标（随机）
             m_enemys[i].random=rand()%4+1;
            if(m_enemys[i].random==1)//上方来敌
            {
            m_enemys[i].m_X = rand()%(GAME_WIDTH-m_enemys[i].m_Rect.width());//随机
            m_enemys[i].m_Y = -m_enemys[i].m_Rect.height();//肯定在屏幕最上方出场
            break;//为啥？？但是必须有
            }
            if(m_enemys[i].random==2)//右方来敌
            {
                m_enemys[i].m_X = 0;//-m_enemys[i].m_Rect.width();//肯定在屏幕最右出场
                m_enemys[i].m_Y = rand()%(GAME_HEIGHT-m_enemys[i].m_Rect.height());//随机
            }
            if(m_enemys[i].random==3)//下方来敌
            {
                m_enemys[i].m_X = rand()%(GAME_WIDTH-m_enemys[i].m_Rect.width());//随机
                m_enemys[i].m_Y = 0;//肯定在屏幕最下方出场
            }
            if(m_enemys[i].random==4)//左方来敌
            {
                m_enemys[i].m_X = m_enemys[i].m_Rect.width();//-m_enemys[i].m_Rect.width();//肯定在屏幕最左出场
                m_enemys[i].m_Y = rand()%(GAME_HEIGHT-m_enemys[i].m_Rect.height());//随机
            }


        }
    }
}

void Mainscence::collisionDetection()//子弹和飞机
{
    //遍历所有非空闲敌机
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemys[i].m_Free)
        {
            continue;//一个一个找
        }
        //遍历所有非空闲子弹
        for(int j=0;j<BULLET_NUM;j++)
        {
            if(m_hero.m_bullets[j].m_Free)
            {
                continue;//一个一个找到
            }
            //如果子弹和飞机相交，碰撞，二者均变空闲
            if(m_enemys[i].m_Rect.intersects(m_hero.m_bullets[j].m_Rect))//子弹和敌机碰撞
            {
                m_enemys[i].m_Free = true;
                m_hero.m_bullets[j].m_Free = true;

                //播放爆炸效果
               for(int i=0;i<BOMB_NUM;i++)
               {
                   if(m_bombs[i].m_Free)
                   {
                       //播放爆炸音效
                       QSound::play(SOUND_BOMB);
                       //空闲爆炸，可以播放爆炸
                       m_bombs[i].m_Free=false;
                       //更新爆炸坐标
                       m_bombs[i].m_X=m_enemys[i].m_X;
                        m_bombs[i].m_Y=m_enemys[i].m_Y;
                        break;
                   }
               }
            }
            if(m_enemys[i].m_Rect.intersects(m_hero.m_Rect))//敌机和hero碰撞
            {


//                QMessageBox msgBox;
//                        msgBox.setText("Game Over");
//                        msgBox.setInformativeText("你挂科了");
//                        msgBox.setStandardButtons(QMessageBox::Ok);
//                        msgBox.setDefaultButton(QMessageBox::Ok);

//                        int ret = msgBox.exec();
//                        if (ret == QMessageBox::Ok)
//                        {
//                            emit BackToMenu(); // 发送信号返回上一界面
//                            this->hide();
//                        }

                QMessageBox::about(this,"Game Over","你挂科了！");
                QCoreApplication::quit();
//                m_Timer.stop();
//                emit BackToMenu();
//                this->hide();
            }

        }

        for(int i=0;i<ENEMY_NUM;i++)
        {
            for(int j=0;j<BULLET_NUM;j++)
            {
                if(m_enemys[i].e_bullets[j].m_Free)
                {
                    continue;
                }


                if(m_hero.m_Rect.intersects(m_enemys[i].e_bullets[j].m_Rect))
                {
                    QMessageBox::about(this,"Game Over","你挂科了！");
                    QCoreApplication::quit();
                }
            }
        }
    }
}

void Mainscence::initScene()//初始化场景
{
    //设置窗口固定尺寸

    setFixedSize(GAME_WIDTH,GAME_HEIGHT);//后期大小只需在h文件中修改即可
    //设置标题
    setWindowTitle(GAME_TITLE);

    //加载图标
    setWindowIcon(QIcon(GAME_ICON));

    //定时器初始化
    m_Timer.setInterval(GAME_RATE);

    //敌机出场时间间隔 初始化
    m_recorder = 0;

    //随机数种子
    srand((unsigned int)time(NULL));
}

void Mainscence::last()
{
    this->show();
    this->playGame();
}



